package com.newhero.product.generator;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PropertiesLoaderUtils;
import com.newhero.product.common.mybatis.generator.AutoGenerator;
import com.newhero.product.common.mybatis.generator.InjectionConfig;
import com.newhero.product.common.mybatis.generator.config.DataSourceConfig;
import com.newhero.product.common.mybatis.generator.config.FileOutConfig;
import com.newhero.product.common.mybatis.generator.config.GlobalConfig;
import com.newhero.product.common.mybatis.generator.config.PackageConfig;
import com.newhero.product.common.mybatis.generator.config.StrategyConfig;
import com.newhero.product.common.mybatis.generator.config.po.TableInfo;
import com.newhero.product.common.mybatis.generator.config.rules.NamingStrategy;
import com.newhero.product.common.mybatis.toolkit.StringUtils;

/**
 * 代码自动构建工具
 */
public class CodeGenerator {

	public static void main(String[] args) {
		// 待调整配置
		// 生成文件路径
		String outputDir = "F:/generator/code";
		final String viewOutputDir = outputDir + "/ftl/";
		String controllerName = "web.controller";// 控制器包名
		String modelName = "persistence.entity";// 实体包名
		String serviceName = "service";
		String serviceImplName = "service.impl";
		String mapperName = "persistence.mapper";

		// 自定义包路径 及操作表
		// String packagepath = "com.newhero.eodi.app.sendfile";
		// String[] tables = new
		// String[]{"EODI_SENDADDRESS","EODI_SENDATTCH","EODI_SENDFILE_SEQ","EODI_SENDIDEA","EODI_SENDPROCESS","EODI_SENDPROCESSDEF","EODI_SENDRANGE"};
		// String packagepath = "com.newhero.eodi.app.rcvfile";
		// String[] tables = new
		// String[]{"EODI_RCVATTCH","EODI_RCVFILE","EODI_RCVFILE_SEQ","EODI_RCVFILE_SEQDEF","EODI_RCVIDEA","EODI_RCVPROCESS","EODI_RCVPROCESSDEF"};
		String packagepath = "com.newhero.product.sjzex";
		String[] tables = new String[] {"szf_sw_organ","web_notice","web_notice_log"};
		
		final String modulename = "webservice";// 父包模块名
		// 代码作者
		String author = "zlf";

		/* 获取 JDBC 配置文件 */
		Properties props = getProperties();
		AutoGenerator mpg = new AutoGenerator();
		// 全局配置
		GlobalConfig gc = new GlobalConfig();
		gc.setOutputDir(outputDir);
		gc.setFileOverride(true);
		gc.setActiveRecord(false);// 开启 activeRecord 模式
		gc.setEnableCache(false);// XML 二级缓存
		gc.setBaseResultMap(true);// XML ResultMap
		gc.setBaseColumnList(false);// XML columList
		gc.setAuthor(author);

		// 自定义文件命名，注意 %s 会自动填充表实体属性！
		gc.setMapperName("%sMapper");
		gc.setXmlName("%sMapper");
		gc.setServiceName("I%sService");
		gc.setServiceImplName("%sServiceImpl");
		gc.setControllerName("%sController");
		mpg.setGlobalConfig(gc);

		// 数据源配置
		DataSourceConfig dsc = new DataSourceConfig();
		dsc.setDriverName(props.getProperty("db.master.driver"));
		dsc.setUsername(props.getProperty("db.master.user"));
		dsc.setPassword(props.getProperty("db.master.password"));
		dsc.setUrl(props.getProperty("db.master.url"));
		mpg.setDataSource(dsc);

		// 策略配置
		StrategyConfig strategy = new StrategyConfig();
		strategy.setCapitalMode(true);// 全局大写命名
		strategy.setDbColumnUnderline(true);// 全局下划线命名
		// strategy.setTablePrefix(new String[] { "SYS_"});//
		// 此处可以修改为您的表前缀
		strategy.setNaming(NamingStrategy.underline_to_camel);// 表名生成策略 下划线转驼峰命名
		strategy.setInclude(tables); // 需要生成的表
		// strategy.setExclude(new String[]{"test"}); // 排除生成的表
		// 字段名生成策略
		// strategy.setFieldNaming(NamingStrategy.underline_to_camel);
		// 自定义实体父类
		// strategy.setSuperEntityClass("com.baomidou.demo.TestEntity");
		// 自定义实体，公共字段
		// strategy.setSuperEntityColumns(new String[] { "test_id", "age" });
		// 自定义 mapper 父类
		strategy.setSuperMapperClass("com.newhero.product.common.mybatis.mapper.BaseMapper");
		// 自定义 service 父类
		strategy.setSuperServiceClass("com.newhero.product.common.service.IBaseService");
		// 自定义 service 实现类父类
		strategy.setSuperServiceImplClass("com.newhero.product.common.service.impl.BaseServiceImpl");
		// 自定义 controller 父类
		strategy.setSuperControllerClass("com.newhero.product.common.controller.BaseController");
		// 【实体】是否生成字段常量（默认 false）
		// public static final String ID = "test_id";
		// strategy.setEntityColumnConstant(true);
		// 【实体】是否为构建者模型（默认 false）
		// public User setName(String name) {this.name = name; return this;}
		// strategy.setEntityBuliderModel(true);
		mpg.setStrategy(strategy);

		// 包配置
		PackageConfig pc = new PackageConfig();
		pc.setModuleName(modulename); // 所属模块
		pc.setParent(packagepath); // 自定义包路径
		pc.setController(controllerName); // 这里是控制器包名，默认 web
		pc.setEntity(modelName);
		pc.setService(serviceName);
		pc.setServiceImpl(serviceImplName);
		pc.setMapper(mapperName);
		mpg.setPackageInfo(pc);

		// 注入自定义配置，可以在 VM 中使用 cfg.abc 设置的值
		InjectionConfig cfg = new InjectionConfig() {
			@Override
			public void initMap() {
			}
		};

		// 生成的模版路径，不存在时需要先新建
		File viewDir = new File(viewOutputDir);
		if (!viewDir.exists()) {
			viewDir.mkdirs();
		}

		List<FileOutConfig> focList = new ArrayList<FileOutConfig>();
		focList.add(new FileOutConfig("/templates/form.ftl.vm") {
			@Override
			public String outputFile(TableInfo tableInfo) {
				return getGeneratorViewPath(viewOutputDir, modulename, tableInfo, "Form.ftl");
			}
		});
		focList.add(new FileOutConfig("/templates/list.ftl.vm") {
			@Override
			public String outputFile(TableInfo tableInfo) {
				return getGeneratorViewPath(viewOutputDir, modulename, tableInfo, "List.ftl");
			}
		});

		cfg.setFileOutConfigList(focList);

		mpg.setCfg(cfg);

		// 执行生成
		mpg.execute();
	}

	/**
	 * 获取配置文件
	 * 
	 * @return 配置Props
	 */
	private static Properties getProperties() {
		// 读取配置文件
		Resource resource = new ClassPathResource("/config/application.properties");
		Properties props = new Properties();
		try {
			props = PropertiesLoaderUtils.loadProperties(resource);
		} catch (IOException e) {
			e.printStackTrace();
		}
		return props;
	}

	/**
	 * 页面生成的文件名
	 */
	private static String getGeneratorViewPath(String viewOutputDir, String modelName, TableInfo tableInfo,
			String suffixPath) {
		String name = StringUtils.firstToLowerCase(tableInfo.getEntityName());
		String path = viewOutputDir + "/" + modelName + "/" + name + "/" + name + suffixPath;
		File viewDir = new File(path).getParentFile();
		if (!viewDir.exists()) {
			viewDir.mkdirs();
		}
		return path;
	}
}
